package com.distribute.framework.core.web.helper;

import com.distribute.framework.core.web.helper.Utils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.MappedByteBuffer;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.springframework.context.ApplicationContext;

import com.distribute.framework.core.lang.Protocol;
import com.distribute.framework.core.lang.ScriptJava;
import com.distribute.framework.core.lsf.Lsf;
import com.distribute.framework.core.sql.cache.KVCacheByFile;
import com.distribute.framework.core.util.Function;
import com.distribute.framework.core.util.Meet;
import com.distribute.framework.core.web.node.Export;
import com.distribute.framework.core.web.util.Ctrl;
import com.distribute.framework.core.web.util.JSEncode;
import com.distribute.framework.core.xwork.WebContext;

public class WebHelper
{	
	static{
		TimeZone.setDefault(TimeZone.getTimeZone("GMT+08:00"));
	}
	
	public final static String UTF8="UTF-8";
	public final static String GBK="GBK";
	
	
	/********************************************************
	 * 线程变量队列
	 ********************************************************/
	static ThreadLocal threadLocal = new ThreadLocal();
	public static void setLocal(Object key,Object object){
		getLocal().put(key, object);
	}
	public static Map<Object,Object> getLocal(){
		Map<Object,Object> map = (Map) threadLocal.get();	
		if(map==null){
			map = new HashMap();
			threadLocal.set(map);
		}
		return map;
	}
	public static <T> T getLocal(Object key){
		return (T)getLocal().get(key);
	}
	/**********************************************************/
	
	
	/********************************************************
	 * 事件监听器
	 ********************************************************/
	public static Map<String,List<Function>> monitor = new HashMap();
	public static void on(String flag,Function function) throws Exception{
		List<Function> list = monitor.get(flag);
		if(list == null){
			monitor.put(flag, list = new ArrayList());
		}
		if(list.size()>256)
			throw new Exception("事件["+flag+"]监听超过256");
		list.add(function);
	}
	public static void fire(String flag){
		List<Function> list = monitor.get(flag);
		if(list == null)return;
		for(Function function:list){
			try{
				function.execute();
			}catch(Exception ex){
				ex.printStackTrace();
			}
		}
	}	
	
	/**
	 * 排队执行过程
	 * @param function
	 * @return 
	 */
	public synchronized static Object queue(Function function){
		try {
			return function.execute();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	
	
	/**
	 * request 参加会议
	 * @param token 等谁
	 * @param param 参数
	 * @param functions 完成执行 
	 * @throws Exception 
	 */
	public static void meet(String waitToken,String selfToken,Meet meeter){
		List<Meet> meets = getMeets(waitToken,selfToken,meeter);		
		if(Utils.equals(waitToken, selfToken)){//会议主持者
			Object[] objects = new Object[meets.size()];
			for(int i=0;i<meets.size();i++)
				objects[i]=meets.get(i).object;
			try{//只有任何一个发生错误，则全部抛出错误
				for(Meet meet:meets)
					meet.execute(objects);
			}catch(Exception ex){
				for(Meet meet:meets)
					meet.exception = ex;
			}finally{//
				Exception exception = null;
				for(Meet meet:meets){//只有任何一个发生错误，则全部抛出错误
					if(meet.exception!=null)
						exception = meet.exception;
				}
				for(Meet meet:meets){//只有任何一个发生错误，则全部抛出错误
					meet.exception = exception;
					meet.meeted = true;
				}
			}
		}
		while(meeter.meeted==false){
			try{Thread.sleep(50);} catch (Exception e) {}
			if((new Date().getTime()-meeter.start.getTime())>(1000*30)){
				meeter.exception = new Exception("多个表单同步提交超时");
				break;
			}
		}
		if(meeter.exception!=null)
			throw new RuntimeException(meeter.exception);
	}
	/**
	 * 参加会议
	 * @param waitToken
	 * @param selfToken
	 * @param meeter
	 * @return
	 */
	private synchronized static List<Meet> getMeets(String waitToken,String selfToken,Meet meeter){
		List meets = Utils.getSession(selfToken);//获取自己主持的会议
		if(meets==null)
			meets = Utils.getSession(waitToken);//获取等待者主持的会议
		if(meets==null)
			meets = new ArrayList();
		Utils.setSession(waitToken, meets);
		Utils.removeSession(selfToken);
		meets.add(meeter);	
		return meets;
	}
	
	
	public static void initSpring(ApplicationContext applicationContext){
		SpringBeanHelper.initSpring(applicationContext);
	}

	/**
	 * 获取一个被spring托管的bean
	 * @param name
	 * @return
	 */
	public static <T> T GetSpringBean(String name)
	{
		return SpringBeanHelper.GetBean(name);
	}
	public static <T> T GetBean(String name)
	{
		return SpringBeanHelper.GetBean(name);
	}
	public static <T> T getBean(String name)
	{
		return SpringBeanHelper.GetBean(name);
	}
	public static Lsf getLsf(){
		return Lsf.getLsf();
	}
	
	
	/**
	 * 获取SKU属性
	 * @param data
	 * @param keys
	 * @return
	 */
	public static List<Map> sku(String data,String...keys){
		List<Map> skus = new ArrayList();
		String[] array = data.split(",");
		for(String item:array){
			Map sku = new HashMap();
			String[] values = item.replaceFirst("#", "").split("#");
			for(int i=0;i<keys.length;i++){
				sku.put(keys[i], values[i]);
			}
			skus.add(sku);
		}
		return skus;
	}
	public static String sku(List<Map> data,String...keys){
		String skuString = "";
		for(Map sku:data){
			if(!Utils.empty(skuString))
				skuString+=",";
			skuString += "#";
			for(String key:keys){
				skuString+=sku.get(key)+"#";
			}
		}
		return skuString;
	}
	
	
	/**
	 * Ajax数据写入客户端
	 * @param content 内容
	 * @param encode 编码，默认utf-8
	 * @return
	 */
	public static String SendAjax(Object object,String encode){
		HttpServletResponse response = WebContext.getServletResponse(); 
		response.setCharacterEncoding(encode==null?"utf-8":encode); 
		response.setContentType("text/plain");
        PrintWriter out=null;			
		try {
			out = response.getWriter();
			if(object instanceof String)
				out.print(object);
			else
				out.print(WebHelper.json(object));
		} catch (IOException e) {
			e.printStackTrace();
		} 
		out.flush(); 
		out.close();
		return null;
	}
	
	
	/**
	 * JsonP数据写入客户端
	 * @param content 内容
	 * @param encode 编码，默认utf-8
	 * @return
	 */
	public static String SendJsonp(String callback,Object object,String encode){
		return Utils.SendHtml(Utils.or(callback, "")+"("+Utils.json(object)+")",encode);
	}
	
	public static String sendAjax(Object object,String encode){
		return Utils.SendHtml("("+Utils.json(object)+")",encode);
	}
	public static String sendAjax(String jsonpCallback,Object object,String encode){
		return Utils.SendHtml(Utils.or(jsonpCallback, "")+"("+Utils.json(object)+")",encode);
	}
	public static Protocol protocol(Boolean success, String message){
		return Protocol.create(success, message);
	}
	public static Protocol protocol(Boolean success, String message,String error){
		return Protocol.create(success, message, error);
	}
	public static Protocol protocol(Boolean success, String message,String error,String attach){
		return Protocol.create(success, message, error,attach);
	}
	
	
	/**
	 * Ajax数据写入客户端
	 * @param content 内容
	 * @param encode 编码，默认utf-8
	 * @return
	 */
	public static String SendHtml(String content,String encode){
		HttpServletResponse response = WebContext.getServletResponse(); 
		response.setCharacterEncoding(encode==null?"utf-8":encode); 
		response.setContentType("text/html");
        PrintWriter out=null;			
		try {
			out = response.getWriter();
			out.print(content);
		} catch (IOException e) {
			e.printStackTrace();
		} 
		out.flush(); 
		out.close();
		return null;
	}
		
	/**
	 * 转跳
	 * @param strUrl
	 * @return
	 */
	public static String Redirect(String strUrl){		
		try{
			HttpServletResponse response = WebContext.getServletResponse(); 
			response.setStatus(301);
			response.setHeader("Location", strUrl);
			response.sendRedirect(strUrl);
		} catch (Exception ex){
			ex.printStackTrace();
		}
		return null;
	}
	
	
	public static String getUrlPath(){
		HttpServletRequest request = WebContext.getServletRequest();
		//放置路径
		String path = request.getContextPath();
		String port="";
		if(request.getServerPort()!=80)
			port=":"+request.getServerPort();
		return request.getScheme()+"://"+request.getServerName()+port+path+request.getServletPath();
	}
	public static String getLocation(){
		return getUrlPath();
	}
	
	
	/**
	 * 转跳到返回之前的地址
	 * @param strUrl
	 * @return
	 */
	public static String RedirectBack(String charset){
		try{
			HttpServletRequest request = WebContext.getServletRequest();
			HttpServletResponse response = WebContext.getServletResponse();
			String strDirect=request.getHeader("Referer");//源地址
			Map params = request.getParameterMap();
			String querys = ParamHelper.getQueryString(params, charset);
			if(querys==null)
				querys="";
			response.sendRedirect(strDirect+"?"+querys);
		} catch (Exception ex){
			ex.printStackTrace();
		}
		return null;
	}
			
	/**
	 * 添加requset项,不返回值
	 * @param name
	 * @param o
	 */
	public static void SetRequest(String name,Object value){
		setRequest(name,value);
	}
	/**
	 * 添加requset项,并返回值
	 * @param name
	 * @param o
	 */
	public static <T> T setRequest(String name,Object value){
		try{
			HttpServletRequest request = WebContext.getServletRequest();
			if(request==null)return null;
			if(name.endsWith("[]")){
				name = name.replace("[]", "");
				List list = (List) request.getAttribute(name);
				if(list==null)list=new ArrayList();
				list.add(value);
				request.setAttribute(name, list);
			}else{
				request.setAttribute(name, value);
			}
			return (T) value;
		}catch(Exception ex){
			return (T) value;
		}
	}
	
	
	/**
	 * 添加requset或pageContext项,不返回值
	 * @param name
	 * @param o
	 */
	public static void Set(String name,Object value){
		SetRequest(name,value);
	}
	
	/**
	 * 添加requset或pageContext项,不返回值
	 * @param name
	 * @param o
	 */
	public static <T> T set(String name,T value){
		SetRequest(name,value);
		return value;
	}
	
	public static Ctrl CTRL(Object value){
		if(value==null)return null;
		if(value instanceof String)
			return Ctrl.fromJsonString((String)value,false);
		if(value instanceof Map)
			return Ctrl.fromMap((Map)value,false);
		return null;
	}
	
	/**
	 * 从request中取值
	 * @param name
	 * @param o
	 */
	public static  <T> T GetRequest(String name){
		HttpServletRequest request = WebContext.getServletRequest();
		return (T)(request==null?null:request.getAttribute(name));
	}
	public static  <T> T getRequest(String name){
		return GetRequest(name);
	}
	
	/**
	 * 添加requset项,并返回值
	 * @param name
	 * @param o
	 */
	public static <T> T executeFunction(String name,Object value){
		Function function = Utils.getRequest(name);
		try {
			return (T) (function==null?null:function.execute(value));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 取COOKIE
	 */
	public static Cookie getCookie(String key)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		Cookie[] cookies = request.getCookies();
		if(cookies!=null)
			for(Cookie cookie:cookies){
				if(cookie.getName().equals(key))
					return cookie;
			}
		return null;
	}
	
	/**
	 * 取COOKIE值
	 */
	public static String getCookieValue(String key)
	{
		Cookie cookie=getCookie(key);
		if(cookie!=null)
			return cookie.getValue();
		return null;
	}
	
	/**
	 * 设置cookie
	 * @param key
	 * @param value
	 */
	public static void setCookie(String path,String key,String value)
	{		
		HttpServletResponse response = WebContext.getServletResponse();
		Cookie cookie = new Cookie(key,value);
		cookie.setMaxAge(60*60*24*30);//默认cookie保存1个月
		cookie.setPath(path);
		response.addCookie(cookie);
	}
	
	/**
	 * 删除cookie
	 * @param key
	 */
	public static void delCookie(String key)
	{
		HttpServletResponse response = WebContext.getServletResponse();
		HttpServletRequest request = WebContext.getServletRequest();
		Cookie[] cookies = request.getCookies();
		if(cookies!=null)
			for(Cookie cookie:cookies){
				String strCookieName=cookie.getName();
				if(strCookieName.equals(key)){
					cookie.setMaxAge(0);
					cookie.setPath(cookie.getPath());
					response.addCookie(cookie);	
				}
			}
	}
	
	public static Boolean equals(String v1,String v2)
	{
		if(v1==null && v2==null)
			return true;
		if(v1!=null && v2!=null && v1.equals(v2))
			return true;
		else
			 return false;
	}
	
	public static <T> Boolean equals(T v1,T v2)
	{
		if(v1==null && v2==null)
			return true;
		if(v1!=null && v2!=null && v1.equals(v2))
			return true;
		else
			 return false;
	}
	
	
	public static void fms(Map map,String key,Object a,Object b){
		if(!Utils.fmp(a))map.put(key,a);
		if(!Utils.fqs(a, b))map.put(key+"$",b);
	}
	
	
	/**
	 * 空内容判断
	 * @param objct
	 * @return
	 */
	public static Boolean fmp(Object objct){
		if(objct==null || objct.toString().trim().equals(""))
			return true;
		return false;
	}
	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static <T> Boolean fqs(Object v1,Object v2){
		if(Utils.fmp(v1)||Utils.fmp(v2))return true;
		if(v1.toString().equals(v2.toString()))
			return true;
		else
			 return false;
	}
	
	
	public static <T> T or(T v1,T v2){
		if(v1==null)
			return v2;
		if(v1.getClass()==String.class && Utils.empty((String)v1))
			return v2;
		return v1;
	}
	
	public static <T> T or(T... vs){
		for(T v:vs){
			if(v!=null)return v;
		}
		return null;
	}
	
	public static Integer bit(Object na,String o,Object nb){
		if(na==null || nb==null)
			return null;
		Integer a = parseInt(na);
		Integer b = parseInt(nb);
		if(o.equals("&"))
			return a & b;
		if(o.equals("|"))
			return a | b;
		if(o.equals(">>"))
			return a >> b;
		if(o.equals("<<"))
			return a << b;
		if(o.equals("^"))
			return a ^ b;
		return null;
	}
	
	public static void trace(Object...objects)
	{
		for(int i=0;i<objects.length;i++){
			if(i>0)
				System.out.print(",");
			System.out.print(objects[i]);
		}
		System.out.println();
	}	
	
	
	/**
	 * 取Session
	 */
	public static  <T> T getSession(String key){
		return getSession(key,null);
	}
	
	/**
	 * 取Session
	 */
	public static  <T> T getSession(String key,Object defaultValue)
	{
		try{
			HttpServletRequest request = WebContext.getServletRequest();
			if(request==null)return null;
			HttpSession session = request.getSession();
			if(session==null)return null;
			Object value = session.getAttribute(key);		
			return (T) (value==null?defaultValue:value);
		}catch(Exception ex){
			Utils.trace(ex.getMessage());
		}
		return null;
	}
	
	/**
	 * 设置Session,不返回值
	 * @param key
	 * @param value
	 */
	public static void SetSession(String key,Object value)
	{		
		setSession(key,value);
	}
	/**
	 * 设置Session,并且返回值
	 * @param <T>
	 * @param key
	 * @param value
	 * @return
	 */
	public static <T> T setSession(String key,Object value)
	{		
		HttpServletRequest request = WebContext.getServletRequest();
		HttpSession session = request.getSession();
		if(value==null)
			removeSession(key);
		else
			session.setAttribute(key, value);
		return (T) value;
	}
	
	/**
	 * 删除Session
	 * @param key
	 */
	public static void removeSession(String key)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		HttpSession session = request.getSession();
		session.removeAttribute(key);
	}
	
	
	
	static Map<String,Cache> caches = new HashMap();
	static class Cache{
		public Object data;
		public Date time;
		public Long expise;//有效时间
		public Cache(Object data2, Long expise2) {
			this.data=data2;
			this.expise=expise2;
			this.time = new Date();
		}
	}
	public static <T> T getCache(String key) {
		Cache cache = caches.get(key);
		if(cache==null)return null;
		if((new Date().getTime()-cache.time.getTime())>cache.expise)
			return null;
		return (T) cache.data;
	}	
	public static void setCache(String key,Object data,Long expise){
		Cache cache = new Cache(data,expise);
		caches.put(key, cache);
	}
	
	/**
	 * 缓存html
	 * @param path
	 */
	public static void cache(String path) {
		Utils.setRequest("cache.html.path",path);
	}
	
	/**
	 * 文件方式键值缓存
	 * @param flag
	 * @param key
	 * @param value
	 */
	public static String cache(String flag,Number key,String value){
		return KVCacheByFile.set(flag, key.longValue(), value);
	}
	public static String cache(String flag,Number key){
		return KVCacheByFile.get(flag, key.longValue());
	}
	
	
	
	/**
	 * 直接实例化Map类,有如Utils.add(key,value).add(key,value).add(key,value)这样
	 * @param key
	 * @param value
	 * @return
	 */
	public static LzMap Map(String key,Object value){
		LzMap map = new LzMap();
		map.put(key, value);
		return map;
	}
	public static LzMap add(String key,Object value){
		LzMap map = new LzMap();
		map.put(key, value);
		return map;
	}
	public static LzMap $(String key,Object value){
		LzMap map = new LzMap();
		map.put(key, value);
		return map;
	}
	public static LzMap Map(){
		LzMap map = new LzMap();
		return map;
	}
	public static class LzMap extends LinkedHashMap{
		public LzMap add(String key,Object value){
			this.put(key, value);
			return this;
		}
		public LzMap $(String key,Object value){
			this.put(key, value);
			return this;
		}
	}
	
	
	public static <T> T parse(Object object, Class<T> type) {
		String typeName = type.getSimpleName();
		Object value = null;
		if(typeName.equals("String"))
			value=Utils.parseString(object);
		else if(typeName.equals("Date"))
			value=Utils.parseDate(object);
		else if(typeName.equals("Boolean"))
			value=Utils.parseBoolean(object);
		else if(typeName.equals("Byte"))
			value=Utils.parseByte(object);
		else if(typeName.equals("Float"))
			value=Utils.parseFloat(object);
		else if(typeName.equals("Double"))
			value=Utils.parseDouble(object);
		else if(typeName.equals("Long"))
			value=Utils.parseLong(object);
		else if(typeName.equals("Integer"))
			value=Utils.parseInteger(object);
		else if(typeName.equals("Short"))
			value=Utils.parseShort(object);
		return (T) value;
	}
	
	
	public static <T> T toObject(Map map, Class<T> entityClass) {
		try{
			T object=entityClass.newInstance();
			if(object instanceof Map){
				return (T) map;
			}
			Field[] fields = entityClass.getDeclaredFields();
			for(Field field:fields){
				String fieldName = field.getName();
				String fieldType = field.getType().getSimpleName();
				Object fieldValue=null;
				if(fieldType.equals("String")){
					fieldValue=Utils.parseString(map.get(fieldName));
					if(Utils.empty(Utils.str(fieldValue))){
						fieldValue = null;
					}
				}else if(Utils.empty(Utils.str(map.get(fieldName))))
					fieldValue = null;
				else if(fieldType.equals("Date"))
					fieldValue=Utils.parseDate(map.get(fieldName));
				else if(fieldType.equals("Boolean"))
					fieldValue=Utils.parseBoolean(map.get(fieldName));
				else if(fieldType.equals("Byte"))
					fieldValue=Utils.parseByte(map.get(fieldName));
				else if(fieldType.equals("Float"))
					fieldValue=Utils.parseFloat(map.get(fieldName));
				else if(fieldType.equals("Double"))
					fieldValue=Utils.parseDouble(map.get(fieldName));
				else if(fieldType.equals("Long"))
					fieldValue=Utils.parseLong(map.get(fieldName));
				else if(fieldType.equals("Integer"))
					fieldValue=Utils.parseInteger(map.get(fieldName));
				else if(fieldType.equals("Short"))
					fieldValue=Utils.parseShort(map.get(fieldName));
				
				field.setAccessible(true);
				if(fieldValue!=null)
					field.set(object, fieldValue);
			}
			
			return object;
		}catch(Exception ex){
			 throw new RuntimeException(ex);
		}
	}
	
	
	public static int rand(Integer iMax)
	{
		return Math.abs(new java.util.Random().nextInt() % iMax);
	}
	
	public static String comma(java.lang.Object flag)
	{
		if(Utils.getRequest("comma_"+flag)!=null){
			return ",";
		}else{
			Utils.setRequest("comma_"+flag, true);
			return "";
		}
	}
	
	public static Date now(){
		return new Date();
	}
		
	public static String date(java.util.Date date, String format) {
		String dateStr = "";
		if (date == null)
			return null;
		if (format == null)
			format = "yyyy-MM-dd HH:mm:ss";
		try {
			SimpleDateFormat DF = new SimpleDateFormat(format);
			dateStr = DF.format(date);
		} catch (Exception e) {
			e.printStackTrace();

		}
		return dateStr;
	}
	
	public static Date date(String date, String format) {
		if(date==null || date.equals(""))
			return null;
		if( format==null ||  format.equals(""))
			format = "yyyy-MM-dd HH:mm:ss";
		try{
			return new SimpleDateFormat(format).parse(date);
		} catch (ParseException e){
			e.printStackTrace();
			return null;
		}		
	}
	
	
	public static String date(Object date, String format) {
		if(date==null || date.equals(""))
			return null;
		if( format==null ||  format.equals(""))
			return null;
		if(date.getClass()==String.class)
			return (String) date;
		return date((Date)date,format);
	}
	
	/**
	 * 时间加减
	 * @param date 参考时间
	 * @param amount 加减数量
	 * @param type 类型 - Y:年 M:月 D:日 H:时 m:分 s:秒
	 * @return
	 */
	public static Date date(Date date, int amount, String type) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int field = (Integer) Utils.add("Y", Calendar.YEAR).add("M", Calendar.MONTH).add("D", Calendar.DATE).add("H", Calendar.HOUR).add("m", Calendar.MINUTE).add("s", Calendar.SECOND).get(type);
		calendar.add(field, amount);
		return calendar.getTime();
	}
	
	public static DateExp DateExp(String expression) {
		DateExp dateExp = new DateExp();
		if(Utils.empty(expression))
			return dateExp;
		char dType = expression.charAt(0);
		String[] array = expression.substring(2, expression.length()-1).split(",");
		Calendar calendar = Calendar.getInstance();
		for(int i=0;i<array.length;i++){
			if(Utils.empty(array[i]))
				continue;
			calendar.setTime(new Date());
			int count = Integer.parseInt(array[i]);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			if(dType=='D'){
				calendar.add(Calendar.DATE, -(count-1));
			}else if(dType=='H'){
				calendar.add(Calendar.HOUR, -(count-1));
			}else if(dType=='W'){
				calendar.set(Calendar.DAY_OF_WEEK, 1);
				calendar.add(Calendar.DATE, -(count-1)*7);
			}else if(dType=='M'){
				calendar.set(Calendar.DAY_OF_MONTH, 1);
				calendar.add(Calendar.MONTH, -(count-1));
			}else if(dType=='Y'){
				calendar.set(Calendar.DAY_OF_YEAR, 1);
				calendar.add(Calendar.YEAR, -(count-1));
			}	
			if(i==0)
				dateExp.start = calendar.getTime();
			else
				dateExp.end = calendar.getTime();
		}	
		return dateExp;
	}
	public static class DateExp implements java.io.Serializable{
		public Date start;
		public Date end;
		public Date getStart() {
			return start;
		}
		public void setStart(Date start) {
			this.start = start;
		}
		public Date getEnd() {
			return end;
		}
		public void setEnd(Date end) {
			this.end = end;
		}
	}
	
	/**
	 * 三角指标函数,根据参考数和变数获取指数，返回0到1之前的指标数
	 * @param r 参考数(及格值)
	 * @param n 当变数等于参考值时，返回值为0.7，当变数无穷大时，返回1
	 * x=n/√(n^2+r^2)
	 * @return
	 */
	public static double triangle(Object r,Object n){
		if(r==null||n==null)
			return -1;
		double a = Double.parseDouble(r.toString());
		double b = Double.parseDouble(n.toString());
		double c = Math.sqrt(a*a+b*b);
		return b/c;
	}
	
	/**
	 * 补零对齐
	 * @param value
	 * @param max
	 * @return
	 */
	public static String zerofill(Object value,Integer max){		
		if(value==null)
			return "";
		String strValue=value.toString();
		if(strValue.length()>=max)
			return strValue;
		String strZero="";
		for(int i=0;i<max-strValue.length();i++)
			strZero+="0";		
		return strZero+strValue;
	}
	
	/**
	 * 保留小数位
	 * @param value
	 * @param count,小数位数
	 * @return
	 */
	public static String digit(Object value,Integer count){
		if(value==null)
			value=0d;
		if(count==null)
			count = 2;
		
		String sNum="";
		
		int iii=1;
		for(int i=0;i<count;i++)
			iii*=10;		
		
		String name = value.getClass().getSimpleName().toLowerCase();
		
		if(name.equals("float"))
			sNum=""+new Float(((Float)value+0.000001f)*iii).longValue();
		else if(name.equals("double"))
			sNum=""+new Double(((Double)value+0.0000001d)*iii).longValue();
		else if(name.equals("bigdecimal"))
			sNum=""+new BigDecimal(((BigDecimal)value).doubleValue()*iii).longValue();
		else if(name.equals("long"))
			sNum=""+(Long)value*iii;
		else if(name.indexOf("int")>-1)
			sNum=""+new Long((Integer)value)*iii;
		else
			sNum=""+Long.valueOf(""+value)*iii;
		
		String _="";
		if(sNum.startsWith("-")){
			sNum=sNum.replace("-", "");
			_="-";
		}
				
		for(int i=0;i<(count-sNum.length()+1);i++)
			sNum="0"+sNum;
				
		sNum = sNum.substring(0, sNum.length()-count) + "." + sNum.substring(sNum.length()-count, sNum.length());
		
		if(sNum.startsWith("."))
			sNum="0"+sNum;
				
		return _+sNum;
	}	
	
	public static double scale(int count, Double value)
	{
		if (value == null) {
			return 0.0D;
		}
		BigDecimal b = new BigDecimal(value.doubleValue());
		return b.setScale(count, 4).doubleValue();
	}
	
	
	public static Integer parseInt(Object value){		
		if(value==null)
			return null;
		
		String name = value.getClass().getSimpleName().toLowerCase();
		
		if(name.equals("float"))
			return new Float((Float)value).intValue();
		else if(name.equals("double"))
			return new Double((Double)value).intValue();
		else if(name.equals("bigdecimal"))
			return ((BigDecimal)value).intValue();
		else if(name.equals("long"))
			return ((Long)value).intValue();
		else if(name.indexOf("int")>-1)
			return (Integer)value;
		else
			return Double.valueOf(""+value).intValue();
	}
		
	
	/**
	 * 判断一个id是不是在ids中
	 * @param ids
	 * @param id
	 * @return
	 */
	public static Boolean idin(String ids,Object id)
	{
		if(empty(ids) || id==null)
			return false;
		String[] array = ids.split(",");
		for(String str:array){
			str = Utils.trim(Utils.str(str)).replaceAll("[^\\d]", "");
			String sid = Utils.trim(Utils.str(id)).replaceAll("[^\\d]", "");
			if(Utils.equals(str, sid))
				return true;
		}
		return false;
	}
	
	public static Long parseLong(Object obj){
		if(obj==null)return null;
		String str = Utils.str(obj).replaceAll("[^\\d].*$", "");
		if(Utils.empty(str))return null;
		return Long.parseLong(str);
	}
	public static Double parseDouble(Object obj){
		if(obj==null)return null;
		if(Utils.empty(Utils.str(obj)))return null;
		return Double.parseDouble(Utils.str(obj));
	}
	public static Float parseFloat(Object obj){
		if(obj==null)return null;
		if(Utils.empty(Utils.str(obj)))return null;
		return Float.parseFloat(Utils.str(obj));
	}
	public static Short parseShort(String str){
		if(str==null)return null;
		str = Utils.str(str).replaceAll("[^\\d].*$", "");
		if(Utils.empty(str))return null;
		return Short.parseShort(str);
	}
	public static Short parseShort(Object obj){
		if(obj==null)return null;
		if(Utils.empty(Utils.str(obj)))return null;
		return parseShort(Utils.str(obj));
	}
	public static Byte parseByte(Object obj){
		if(obj==null)return null;
		if(Utils.empty(Utils.str(obj)))return null;
		return parseByte(Utils.str(obj));
	}
	public static Byte parseByte(String str){
		if(str==null)return null;
		str = Utils.str(str).replaceAll("[^\\d].*$", "");
		if(Utils.empty(str))return null;
		return Byte.parseByte(str);
	}
	
	public static Integer parseInteger(Object obj){
		if(obj==null)return null;
		if(Utils.empty(Utils.str(obj)))return null;
		return parseInt(obj);
	}
	public static Integer parseInt(String str){
		if(str==null)return null;
		str = Utils.str(str).replaceAll("[^\\d].*$", "");
		if(Utils.empty(str))return null;
		return Integer.parseInt(str);
	}
	public static Boolean parseBoolean(Object obj){
		if(obj==null)return null;
		return parseBool(obj);
	}
	public static String parseString(Object obj){
		if(obj==null)return null;
		return Utils.str(obj);
	}
	public static Date parseDate(Object obj){
		if(obj==null)return null;
		if(obj!=null && obj.getClass()==Date.class)
			return (Date)obj;
		if(Utils.str(obj).matches("[\\d]+"))
			return new Date(Utils.parseLong(obj));
		if(Utils.str(obj).length()>12){
			return Utils.date(Utils.str(obj), "yyyy-MM-dd HH:mm:ss");
		}else{
			return Utils.date(Utils.str(obj), "yyyy-MM-dd");
		}
	}
	public static Boolean parseBool(Object obj){
		if(obj==null)return null;
		Boolean b=null;
		String str = Utils.str(obj);
		if(!Utils.empty(str)){
			try{
				b=Boolean.valueOf(str)||str.equals("1");
			}catch(NumberFormatException e){
				System.out.println("<ParamHelper error> - " + e.getMessage());
			}
		}
		return b;
	}
	
	
	
	
	/**
	 * 判断一个id是不是在ids中
	 * @param ids
	 * @param id
	 * @return
	 */
	public static Boolean bitin(Object src,Object target){
		if(src==null || target==null)
			return false;
		String strSrc = src.toString();
		String strTarget = target.toString();
		if(Utils.empty(strSrc)||Utils.empty(strTarget))
			return false;
		return (Long.parseLong(strSrc) & Long.parseLong(strTarget)) == Long.parseLong(strTarget);
	}
	
	/**
	 * 判断一个id是不是在ids中
	 * @param ids
	 * @param id
	 * @return
	 */
	public static Integer indexOf(String target,String find)
	{
		if(empty(target) || empty(find))
			return -1;
		return target.indexOf(find);
	}
	
	public static String replace(String src,String regex,String replacement)
	{
		if(empty(src) || empty(regex))
			return src;
		return src.replaceAll(regex, replacement);
	}
	
	
	public static String uuid()
	{
		String strUUID=UUID.randomUUID().toString();
		return strUUID.replaceAll("-", "");
	}
	
	public static String trim(String string){	
		if(string==null || string.trim().equals(""))
			return "";	
		return string.trim();
	}
	
	public static String str(Object object){
		if(object==null)
			return null;
		return trim(object.toString());
	}
	
	public static String string(Object object){
		if(object==null)
			return "";
		return trim(object.toString());
	}
	
	public static String left(String string,Integer len){	
		if(empty(string))
			return "";
		string=text(string);
		return string.length()>len?string.substring(0, len)+"...":string;
	}
	
	/**
	 * 把数据库字段转成java格式的
	 * @param name
	 * @return
	 */
	public static String toVarName(String name){	
		if(Utils.empty(name))
			return name;
		String upName="";
		Boolean _=false;
		for(int i=0;i<name.length();i++)
		{
			String ch=""+name.charAt(i);
			if(ch.equals("_"))
			{
				_=true;
			}
			else
			{
				if(_){
					upName+=ch.toUpperCase();
				}
				else{
					upName+=ch;
				}				
				_=false;
			}			
		}
		return upName;
	}
	
	public static String format(String string){
		if(string==null || string.equals(""))
			return string;
		string = toVarName(string);
		return string.toLowerCase();
	}
	public static String FORMAT(String string){
		if(string==null || string.equals(""))
			return string;
		string = toVarName(string);
		return string.toUpperCase();
	}
	public static String forMat(String string){
		if(string==null || string.equals(""))
			return string;
		string = toVarName(string);
		return string.substring(0,1).toLowerCase() + string.substring(1);
	}
	public static String ForMat(String string){
		if(string==null || string.equals(""))
			return string;
		string = toVarName(string);
		return string.substring(0,1).toUpperCase() + string.substring(1);
	}
	public static String Format(String string)
	{
		if(string==null || string.equals(""))
			return string;
		string=toVarName(string);
		string=string.toLowerCase();
		return string.substring(0,1).toUpperCase() + string.substring(1);
	}
	
	/**
	 * 根据名称取子级前缀
	 * @param name  父名子
	 * @param bParentPrefix 是否包含父级前缀
	 * @return
	 */
	public static String prefix(String name,Boolean bParentPrefix)
	{		
		String strPrefix="";
		Boolean _=true;
		for(int i=0;i<name.length();i++)
		{
			String ch=""+name.charAt(i);
			if(ch.equals("_"))
			{
				_=true;
			}
			else
			{
				if(_){
					strPrefix+=ch.toLowerCase();
				}							
				_=false;
			}			
		}
		
		if(bParentPrefix && name.indexOf("_")>0){
			String sParentPrefix=name.substring(0, name.indexOf("_"));
			strPrefix=sParentPrefix+strPrefix.substring(1);
		}
		
		return strPrefix;
	}
	
	/**
	 * 连接字符串,给el表达式用
	 * @param a
	 * @param b
	 * @return
	 */
	public static String join(Object a,Object b)
	{
		if(a==null)
			return ""+b;
		if(b==null)
			return a+"";
		return a+""+b;
	}
	
	public static Boolean empty(String string)
	{
		if(string==null || string.trim().equals(""))
			return true;
		return false;		
	}
	
	public static String or(String a,String b)
	{
		return empty(a)?b:a;
	}
		
	public static Integer size(Object object)
	{
		if(object==null)
			return 0;
		Class cls=object.getClass();
		if(object instanceof java.util.Map)
			return ((Map) object).size();
		else if(cls.isArray())
			return ((Object[]) object).length;
		else if(cls==java.lang.String.class)
			return len((String)object);
		else if(object instanceof java.util.List)
			return ((List)object).size();
		else
			return 0;
	}
	
	public static Integer len(String string)
	{
		return string==null?0:string.length();
	}
	
	public static List split(String string,String regex)
	{
		List list=new ArrayList();
		if(!empty(string)){
			String[] array = string.split(regex);
			for(String s:array)
				list.add(s);
		}
		return list;		
	}
	
	public static Integer splits(String string,String regex)
	{
		return split(string,regex).size();
	}
	
	public static Boolean matches(String string,String regex)
	{
		return string.matches(regex);
	}
	
	
	public static String md5(String string){
		try{
	        MessageDigest md5=MessageDigest.getInstance("MD5");
	        byte[] bytes=md5.digest(string.getBytes("utf-8"));
	        char[] chars = new char[bytes.length * 2];
	        for (int i = 0; i < bytes.length; i++) {
	            int b = bytes[i];
	            chars[i * 2] = hexDigits[(b & 0xF0) >> 4];
	            chars[i * 2 + 1] = hexDigits[b & 0x0F];
	        }        
	        return new String(chars);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 获取页面cookie
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "deprecation" })
	public static Map windowCookie(){
		try{
			String hashcode = String.valueOf(Math.abs(Utils.getLocation().hashCode()));
			String strCookieValue = Utils.getCookieValue(hashcode);
			if(Utils.empty(strCookieValue)){
				Map map = new HashMap();
				map.put("hashcode", hashcode);
				return map;
			}
			Map map = (Map)Utils.eval(URLDecoder.decode(strCookieValue));
			map.put("hashcode", hashcode);
			return map;
		}catch(Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	
	/**
     * @notes 字符串转化为十六进制字符串
     * @param bytes
     * @return String
     */
    public static String HEX(String strString) {
    	if(WebHelper.empty(strString))
    		return "";
    	String strHex = "";
    	for(int i=0;i<strString.length();i++){
    		Integer charCode = new Integer(strString.charAt(i));//取unicode码
    		//charCode = charCode+23; //unicode码变种
    		strHex+=Utils.zerofill(charCode.toString(charCode, 16), 4);//转成十六进制,4位对齐		
    	}
        return strHex.toUpperCase();
    }
    /**
     * @notes 字符串转化为十六进制字符串
     * @param bytes
     * @return String
     */
    public static String XEH(String strHex) {
    	if(WebHelper.empty(strHex))
    		return "";
    	String strString = "";
    	for(int i=0;i<strHex.length();i+=4){
    		String sHex = strHex.substring(i,i+4);//取unicode码
    		int charCode = Integer.valueOf(sHex, 16);
    		//charCode = charCode+23; //unicode码变种
    		strString+=(char)charCode;
    	}
        return strString;
    }
	
	public static char[] hexDigits = 
    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    /**
     * @notes 字符串转化为十六进制字符串
     * @param bytes
     * @return String
     */
    public static String hex(String strString) {
    	if(WebHelper.empty(strString))
    		return "";
    	byte[] bytes=strString.getBytes();
        char[] chars = new char[bytes.length * 2];

        for (int i = 0; i < bytes.length; i++) {
            int b = bytes[i];
            chars[i * 2] = hexDigits[(b & 0xF0) >> 4];
            chars[i * 2 + 1] = hexDigits[b & 0x0F];
        }        
        return new String(chars);
    }
    
    /**
     * @notes 十六进制字符串转化为字符串
     * @param str
     * @return byte[]
     */
    public static String xeh(String str) { 
    	if(WebHelper.empty(str))
    		return "";
        int length = str.length() / 2;
        byte[] bytes = new byte[length];
        byte[] source = str.getBytes();

        for (int i = 0; i < bytes.length; ++i) {
            byte bh = Byte.decode("0x" + new String(new byte[]{source[i * 2]})).byteValue();
            bh = (byte)(bh << 4);
            byte bl = Byte.decode("0x" + new String(new byte[]{source[i * 2 + 1]})).byteValue();
            bytes[i] = (byte)(bh ^ bl);
        }
        return new String(bytes);
    }    
    	
	/**
	 * 去除字附串中的html标签
	 * @param htmlStr
	 * @return
	 */
	public static String text(String htmlStr) {
		java.util.regex.Pattern p_script;
		java.util.regex.Matcher m_script;
		java.util.regex.Pattern p_style;
		java.util.regex.Matcher m_style;
		java.util.regex.Pattern p_html;
		java.util.regex.Matcher m_html;		
		String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
		String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
		String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
		p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
		m_script = p_script.matcher(htmlStr);
		htmlStr = m_script.replaceAll(""); // 过滤script标签
		p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
		m_style = p_style.matcher(htmlStr);
		htmlStr = m_style.replaceAll(""); // 过滤style标签
		p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
		m_html = p_html.matcher(htmlStr);
		htmlStr = m_html.replaceAll(""); // 过滤html标签
		return htmlStr;
	}
	
	
	
	
	
	public static String html(String string){	
		if(string==null || string.trim().equals(""))
			return "";
		string=string.replace("&", "&amp;");
		string=string.replace("<", "&lt;");
		string=string.replace(">", "&gt;");
		string=string.replace(" ", "&nbsp;");
		string=string.replace("\"", "&quot;");
		string=string.replaceAll("\\n", "<br/>");
		string=string.replaceAll("[\\s]", "&nbsp;");
		return string;
	}
	
	
	public static Object htm(Object value){	
		if(value==null || !value.getClass().getSimpleName().equals("String"))
			return value;
		return html((String) value);
	}
	
	public static Object HTM(Object value){	
		if(value==null || !value.getClass().getSimpleName().equals("String"))
			return value;
		String  string = (String) value; 
		if(string==null || string.trim().equals(""))
			return "";
		string=string.replace("&", "&amp;");
		string=string.replace("<", "&lt;");
		string=string.replace(">", "&gt;");
		string=string.replace(" ", "&nbsp;");
		string=string.replace("\"", "&quot;");
		string=string.replaceAll("[\\s]", "&nbsp;");
		return string;
	}
	
	
	public static String ubb(String string) {
		String tString = string;
		if (!tString.equals("")) {
			Boolean tState = true;
			tString = tString.replace("&", "&amp;");
			tString = tString.replace(">", "&gt;");
			tString = tString.replace("<", "&lt;");
			tString = tString.replace("\"", "&quot;");
			tString = tString.replace("&amp;#91;", "&#91;");
			tString = tString.replace("&amp;#93;", "&#93;");
			tString = tString.replaceAll("\\[br\\]", "<br />");
			String[][] tRegexAry = {
		        {"\\[p\\]([^\\[]*?)\\[\\/p\\]", "$1<br />"},
		        {"\\[b\\]([^\\[]*?)\\[\\/b\\]", "<b>$1</b>"},
		        {"\\[i\\]([^\\[]*?)\\[\\/i\\]", "<i>$1</i>"},
		        {"\\[u\\]([^\\[]*?)\\[\\/u\\]", "<u>$1</u>"},
		        {"\\[ol\\]([^\\[]*?)\\[\\/ol\\]", "<ol>$1</ol>"},
		        {"\\[ul\\]([^\\[]*?)\\[\\/ul\\]", "<ul>$1</ul>"},
		        {"\\[li\\]([^\\[]*?)\\[\\/li\\]", "<li>$1</li>"},
		        {"\\[code\\]([^\\[]*?)\\[\\/code\\]", "<div class=\"ubb_code\">$1</div>"},
		        {"\\[quote\\]([^\\[]*?)\\[\\/quote\\]", "<div class=\"ubb_quote\">$1</div>"},
		        {"\\[color=([^\\]]*)\\]([^\\[]*?)\\[\\/color\\]", "<font style=\"color: $1\">$2</font>"},
		        {"\\[hilitecolor=([^\\]]*)\\]([^\\[]*?)\\[\\/hilitecolor\\]", "<font style=\"background-color: $1\">$2</font>"},
		        {"\\[align=([^\\]]*)\\]([^\\[]*?)\\[\\/align\\]", "<div style=\"text-align: $1\">$2</div>"},
		        {"\\[url=([^\\]]*)\\]([^\\[]*?)\\[\\/url\\]", "<a href=\"$1\" target=\"_blank\">$2</a>"},
		        {"\\[img\\]([^\\[]*?)\\[\\/img\\]", "<a href=\"$1\" target=\"_blank\"><img src=\"$1\" onload=\"cls.img.tResize(this, 600, 1800);\" /></a>"}
			};
			while (tState) {
				tState = false;
				for (int ti = 0; ti < tRegexAry.length; ti++) {
					String tvalue1, tvalue2;
					Pattern tPattern = Pattern.compile(tRegexAry[ti][0]);
					java.util.regex.Matcher tMatcher = tPattern.matcher(tString);
					while (tMatcher.find()) {
						tState = true;
			            tvalue1 = tMatcher.group();
			            tvalue2 = tRegexAry[ti][1];
			            for (int tk = 1; tk < (tMatcher.groupCount() + 1); tk ++) tvalue2 = tvalue2.replace("$" + tk, tMatcher.group(tk));
			            tString = tString.replace(tvalue1, tvalue2);
					}
				}
			}
		}
		return tString;
	}
	
	
	public static String js(String string){		
		return JsonHelper.js(string);
	}	
	
	
	public static String json(Object object){
		return JsonHelper.json(object);
	}
	
	public static String JSEncode(String js,String prefix, Boolean bWindow){
		return JSEncode.encode(js, prefix,bWindow);
	}
	
	
	
	/**
	 * json	解析
	 * @param jsonString
	 * @return
	 * @throws Exception 
	 */
	public static Object executeScriptJava(String classname,String javaCode,String[] imports,Object... args) throws Exception{
		return ScriptJava.execute(classname,javaCode,imports,args);
	}
	public static Object executeScriptJava(String classname,String javaCode,Object... args) throws Exception{
		return ScriptJava.execute(classname,javaCode, null, args);
	}
	public static Object executeScriptJava(String classname,String javaCode) throws Exception{
		return ScriptJava.execute(classname,javaCode, null);
	}
	public static ScriptJava createScriptJava(String classname,String javaCode,String[] imports) throws Exception{
		return ScriptJava.create(classname, javaCode, imports);
	}
	public static ScriptJava createScriptJava(String classname,String javaCode) throws Exception{
		return ScriptJava.create(classname, javaCode, null);
	}
	
	/**
     * 解压缩
     * @param data 待压缩的数据
     * @return byte[] 解压缩后的数据
	 * @throws Exception 
     */
    public static String inflater(String string) throws Exception {
    	byte[] data = string.getBytes("ISO-8859-1");    	
        byte[] output = inflater(data); 
        return new String(output,"UTF-8");
    }
    public static byte[] inflater(byte[] data) {
		byte[] output = new byte[0];
        Inflater decompresser = new Inflater();  
        decompresser.reset();  
        decompresser.setInput(data);  
  
        ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);  
        try {  
            byte[] buf = new byte[1024];  
            while (!decompresser.finished()) {  
                int i = decompresser.inflate(buf);  
                o.write(buf, 0, i);  
            }  
            output = o.toByteArray();  
        } catch (Exception e) {  
            output = data;  
            e.printStackTrace();  
        } finally {  
            try {  
                o.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }
        decompresser.end();
		return output;
	}
	
	/**  
     * 字符串deflate压缩  
     * @param str 待压缩的字符串  
     * @return    返回压缩后的字符串  
	 * @throws Exception 
     * @throws IOException  
     */  
    public static String deflate(String str) throws Exception{  
        byte[] inputByte = str.getBytes("UTF-8");
        byte[] bytes = deflate(inputByte);
        return new String(bytes,"ISO-8859-1");
        
    }
	public static byte[] deflate(byte[] inputByte) throws IOException {
		int len = 0;
        Deflater defl = new Deflater();
        defl.setInput(inputByte);
        defl.finish();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] outputByte = new byte[1024];
        try {
            while (!defl.finished()) {
                // 压缩并将压缩后的内容输出到字节输出流bos中
                len = defl.deflate(outputByte);
                bos.write(outputByte, 0, len);
            }
            defl.end();
        } finally {
            bos.close();
        }
        byte[] bytes = bos.toByteArray();
		return bytes;
	}  
	
	/**
	 * json	解析
	 * @param jsonString
	 * @return
	 */
	public static <T> T eval(String jsonString){
		return JsonHelper.eval(jsonString);
	}
	
	
	public static String encode(String string,String charset){
		if(string==null || string.trim().equals(""))
			return "";
		try{
			string=URLEncoder.encode(string,charset);
		} catch (UnsupportedEncodingException e){
			e.printStackTrace();
		}
		return string;
	}
	
	
	public static String keyword(String string,String keyword,Integer len){
		if(empty(string) || empty(keyword))
			return "";			
		string=text(string);
		if(empty(keyword))
			keyword="";
    	String[] keys = keyword.split(" ");
    	if(len>-1){
	    	int start=-1;
	    	for(String key:keys){
	    		int index=string.indexOf(key);
	    		if(index==-1)
	    			continue;
	    		if(start==-1 || index<start)
	    			start=index;
	    	}
	    	start=start-10;
	    	if(start<0)
	    		start=0;
	    	int end=start+len;
	    	if(end>string.length())
	    		end=string.length();
	    	string=string.substring(start, end);
    	}
    	for(String key:keys)
    		string=string.replace(key, "<font class='keyword'>"+key+"</font>");
		return string;
	}	
		
	
	public static String querys(String charset)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		Map params = request.getParameterMap();
		return ParamHelper.getQueryString(params, charset);
	}
	
	public static String querys(String charset,String notAt)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		Map params = request.getParameterMap();
		return ParamHelper.getQueryString(params, charset, notAt);
	}
	public static String queryss(String charset,String notAt,String notAt1)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		Map params = request.getParameterMap();
		return ParamHelper.getQueryString(params, charset, notAt,notAt1);
	}
	public static String querysss(String charset,String notAt,String notAt1,String notAt2)
	{
		HttpServletRequest request = WebContext.getServletRequest();
		Map params = request.getParameterMap();
		return ParamHelper.getQueryString(params, charset, notAt,notAt1,notAt2);
	}
		
	public static String http(String sUrl) throws Exception{
		return http(sUrl,"UTF-8");
	}
	
	public static String http(String sUrl,String encode)throws Exception{	
		String strContent = "";
		HttpURLConnection urlConnection = null;
		URL url = new URL(sUrl);
		urlConnection = (HttpURLConnection) url.openConnection();
		urlConnection.setRequestMethod("GET");
		urlConnection.setConnectTimeout(10000);
		urlConnection.setReadTimeout(10000);
		// urlConnection.setDoOutput(true);
		if (urlConnection.getResponseCode() >= 200 && urlConnection.getResponseCode() < 300) {
			BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),encode));
			String strLine = in.readLine();
			// 得到的结论是文件如果是带bom的utf-8格式的，即使用UTF-8的流读入，也得自己去掉bom才可以
			if (strLine != null && !strLine.equals("")) {
				if (strLine.charAt(0) == (char) 65279)// BOM
					strLine = strLine.substring(1);
			}
			while (strLine != null) {
				strContent += strLine + "\r\n";
				strLine = in.readLine();
			}
			in.close();
		}
		urlConnection.disconnect();
		return strContent;
	}
	
	public static String upload(String action,String fileName){
		Utils.trace("SpiderHelper模拟form上传文件...",action,fileName);
		if(!new File(fileName).exists())
			return Utils.json("{error:1,message:\"未发现有效的文件,放弃上传\"}");
		StringBuffer response = new StringBuffer();
		PostMethod method = new PostMethod(action); 
		try{
			HttpClient client=new HttpClient();
			FilePart[] parts = {new FilePart("file", new File(fileName))};			
			method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));
			client.executeMethod(method);
			 //下面是读取网站的返回网页，例如上传成功之类的 
            //if (method.getStatusCode() == HttpStatus.SC_OK){  
                //读取为 InputStream，在网页内容数据量大时候推荐使用  
                BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(),"UTF-8"));  
                String line=null;
                while ((line = reader.readLine()) != null){  
                     response.append(line);  
                }  
                reader.close();  
           //} 
		}catch(Exception ex){
			ex.printStackTrace();
			return Utils.json("{error:1,message:\"提交表单出现异常\"}");
		}catch(Error er){
			return Utils.json("{error:1,message:\"提交表单出现错误\"}");
		}finally{
			method.releaseConnection();
		}
		String jsonString = response.toString();
		return Utils.json(jsonString);
	}
	
	/**
	 * 以post方式
	 * @param action
	 * @param data
	 * @param encode
	 * @return
	 */
	public static String post(String action,String data,String encode){		
		StringBuffer response = new StringBuffer();
		PostMethod method = new PostMethod(action); 		
		try{
			HttpClient client=new HttpClient();
			method.setRequestBody(data);
			method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,encode);		
			client.executeMethod(method);
			 //下面是读取网站的返回网页，例如上传成功之类的 
            //if (method.getStatusCode() == HttpStatus.SC_OK){  
                //读取为 InputStream，在网页内容数据量大时候推荐使用  
                BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(),encode));  
                String line=null;
                while ((line = reader.readLine()) != null){  
                     response.append(line);  
                }  
                reader.close();  
           // } 
		}catch(Exception ex){
			ex.printStackTrace();
			return Utils.json("{error:1,message:\"提交表单出现异常\"}");
		}catch(Error er){
			return Utils.json("{error:1,message:\"提交表单出现错误\"}");
		}finally{
			method.releaseConnection();
		}
		return response.toString();
	}	
			
	/**
	 * 以post方式请求数据
	 * @param action
	 * @param params
	 * @param encode
	 * @return
	 */
	public static String post(String action,Map<String,String> params,String encode){
		StringBuffer response = new StringBuffer();
		PostMethod method = new PostMethod(action); 		
		try{
			HttpClient client=new HttpClient();
			Set<String> keyset = params.keySet();			
			Part[] parts = new Part[keyset.size()];
			int i=0;
			for(String key:keyset){
				String value =(String) params.get(key);
				parts[i++]=new StringPart(key, value,encode);
			}
			method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,encode);
			method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));			
			client.executeMethod(method);
			 //下面是读取网站的返回网页，例如上传成功之类的 
            if (method.getStatusCode() == HttpStatus.SC_OK){  
                //读取为 InputStream，在网页内容数据量大时候推荐使用  
                BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(),encode));  
                String line=null;
                while ((line = reader.readLine()) != null){  
                     response.append(line);  
                }  
                reader.close();  
            } 
		}catch(Exception ex){
			ex.printStackTrace();
			return Utils.json("{error:1,message:\"提交表单出现异常\"}");
		}catch(Error er){
			return Utils.json("{error:1,message:\"提交表单出现错误\"}");
		}finally{
			method.releaseConnection();
		}
		return response.toString();
	}
	
		
	/**
	 * 根据url地址下载文件
	 * @param url
	 * @param filePathName
	 * @return
	 */
	public static Boolean download(String url,String filePathName) {	
		
		InputStream is=null;
		FileOutputStream fos=null;		
		try {
			filePathName=filePathName.replaceAll("\\\\", "/");
			filePathName=filePathName.replaceAll("//", "/");		
			String filePath=filePathName.substring(0,filePathName.lastIndexOf("/"));		
			if(!new File(filePath).exists())
				new File(filePath).mkdirs();
			
			URL Url = new URL(url);
			URLConnection conn = Url.openConnection();
			conn.connect();
			is = conn.getInputStream();
			int fileSize = conn.getContentLength();// 根据响应获取文件大小
			if (fileSize <= 0) // 获取内容长度为0
				return false;		
			if (is == null)
				return false;
			fos = new FileOutputStream(filePathName); // 创建写入文件内存流，
			byte buf[] = new byte[1024];
			int numread;
			while ((numread = is.read(buf)) != -1)
				fos.write(buf, 0, numread);
			is.close();
			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally{
			if(is!=null)
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if(fos!=null)
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}			
		}
		return false;
	}
	
	
	/**
	 * 数据导出功能
	 * @param count
	 * @param size
	 * @param export
	 * @param rootClass
	 * @param keyELs
	 * @throws Exception 
	 */
	public static void export(int maxCount,int querySize,int pageIndex,Export exporter,Class<?> rootClass,List<String> fieldExpressions) throws Exception{
		Export.export(maxCount, querySize, pageIndex , exporter, rootClass, fieldExpressions);
	}
	public static void export(int maxCount,int querySize,int pageIndex,Export exporter,Class<?> rootClass,String[] fieldExpressions) throws Exception{
		List<String> list = new ArrayList();
		for(String str:fieldExpressions)
			list.add(str);
		Export.export(maxCount, querySize, pageIndex, exporter, rootClass, list);
	}
	
	
	
	/**
	 * 页面字段显示、编辑、查询、默认值策略(默认全部显示，可编辑，可列表,可查询)
	 */
	public static Boolean editable(Map controller,String key){
		return ControllerHelper.editable(controller, key,null);
	}
	public static Boolean visible(Map controller,String key){
		return ControllerHelper.visible(controller, key,null);
	}	
	public static Boolean queryable(Map controller,String key){
		return ControllerHelper.queryable(controller, key,null);
	}
	public static Boolean listable(Map controller,String key){
		return ControllerHelper.listable(controller, key ,null);
	}
	
	
	public static Boolean visibleEx(Map controller,String key,Boolean defaultValue){
		return ControllerHelper.visible(controller, key,defaultValue);
	}
	public static Boolean editableEx(Map controller,String key,Boolean defaultValue){
		return ControllerHelper.editable(controller, key,defaultValue);
	}
	public static Boolean queryableEx(Map controller,String key,Boolean defaultValue){
		return ControllerHelper.queryable(controller, key,defaultValue);
	}
	public static Boolean listableEx(Map controller,String key,Boolean defaultValue){
		return ControllerHelper.listable(controller, key ,defaultValue);
	}	
	
	
	public static Object permission(Map controller,String key){
		return ControllerHelper.permission(controller, key);
	}
	public static void setObjectDefaultValue(Object object,Map map){
		ControllerHelper.setObjectDefaultValue(object, map);
	}	
	public static void executeControllerAfter(Map controller,Object object) throws Exception{
		ControllerHelper.executeControllerAfter(controller, object);
	}
	public static void executeControllerBefore(Map controller,Object object) throws Exception{
		ControllerHelper.executeControllerBefore(controller, object);
	}
	
	
	static Map<String,String> iconfonts=new HashMap();
	static{
		try{
			Map map = Utils.eval(Utils.readFile(WebHelper.class.getResourceAsStream("iconfonts.json"), Utils.UTF8));
			iconfonts = map;
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	public static String getIconfont(String iconPath){
		if(Utils.empty(iconPath))
			return "icon-libreoffice";
		iconPath = iconPath.replace("\\", "/");
		if(iconPath.lastIndexOf("/")>-1)
			iconPath = iconPath.substring(iconPath.lastIndexOf("/")+1);
		return Utils.or(iconfonts.get(iconPath), "icon-libreoffice");
	}
	
	
}